package com.seanchenxi.gwt.wordpress.xmlrpc.service.model.impl;

import java.util.ArrayList;
import java.util.HashMap;

import com.seanchenxi.gwt.wordpress.domain.model.Author;
import com.seanchenxi.gwt.wordpress.domain.model.Blog;
import com.seanchenxi.gwt.wordpress.domain.model.Comment;
import com.seanchenxi.gwt.wordpress.domain.model.CommentCount;
import com.seanchenxi.gwt.wordpress.domain.model.CommentStatus;
import com.seanchenxi.gwt.wordpress.domain.model.CustomField;
import com.seanchenxi.gwt.wordpress.domain.model.Page;
import com.seanchenxi.gwt.wordpress.domain.model.PageList;
import com.seanchenxi.gwt.wordpress.domain.model.PageStatus;
import com.seanchenxi.gwt.wordpress.domain.model.Tag;

public class ModelFactory {
	
	public static Blog ToBlog(Object obj){
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		return new BlogImpl(properties);
	}
		
	public static Page ToPage(Object obj){
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		
		properties.put("custom_fields", ToCustomFields(properties.get("custom_fields")));
		
		for(PageStatus ps : PageStatus.values()){
			if(ps.getValue().equals(properties.get("page_status"))){
				properties.put("page_status", ps);
				break;
			}
		}
		
		return new PageImpl(properties);	
	}
	
	public static PageList ToPageList(Object obj){
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		return new PageImpl(properties);
	}
	
	static CustomField ToCustomField(Object obj){
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		return new CustomFieldImpl(properties);
	}
	
	
	static ArrayList<CustomField> ToCustomFields(Object object){
		if(isNotList(object)) return null;	
		ArrayList<CustomField> customFields = new ArrayList<CustomField>();
		for(Object obj : (ArrayList<?>)object){
			CustomField cf = ToCustomField(obj);
			if(cf!= null && customFields.contains(cf)){
				customFields.add(cf);
			}
		}
		return customFields;
	}
	
	@SuppressWarnings("unchecked")
	public static HashMap<String,Object> castToMap(Object obj){
		if(isNotPropertyMap(obj)) return null;
		return (HashMap<String,Object>)obj;
	}
	
	public static boolean isNotPropertyMap(Object object){
		if(object==null) return true;
		if(!(object instanceof HashMap)) return true;
		if(((HashMap<?, ?>)object).keySet() == null) return true;
		if(((HashMap<?, ?>)object).keySet().size() < 1) return true;
		return false;
	}
	
	public static boolean isNotList(Object object){
		if(object==null) return true;
		if(!(object instanceof ArrayList)) return true;
		if(((ArrayList<?>)object).size() < 1) return true;
		return false;
	}

	@SuppressWarnings("unchecked")
	public static <X>X ToCategory(Object obj) {
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		return (X)new CategoryImpl(properties);
	}

	public static Author ToAuthor(Object obj) {
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		return new AuthorImpl(properties);
	}

	public static Tag ToTag(Object obj) {
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		return new TagImpl(properties);
	}

	public static CommentCount ToCommentCount(Object obj) {
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		return new CommentCountImpl(properties);
	}

	public static Comment ToComment(Object obj) {
		HashMap<String,Object> properties = castToMap(obj);
		if(properties == null) return null;
		
		for(CommentStatus cs : CommentStatus.values()){
			if(cs.getValue().equals(properties.get("status"))){
				properties.put("status", cs);
				break;
			}
		}
		
		return new CommentImpl(properties);
	}

}
